﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace PowerWaveAddin
{
	[XmlRootAttribute(ElementName = "UploadConfigData", IsNullable = false)]
	public class UploadConfigData
	{
		private static UTF8Encoding encoding = new UTF8Encoding();

		public delegate void UploadConfigDataChangedHandler(object sender, EventArgs e);

		private event UploadConfigDataChangedHandler m_UploadConfigDataChanged;
		public event UploadConfigDataChangedHandler UploadConfigDataChanged
		{
			add { m_UploadConfigDataChanged += value; }
			remove { m_UploadConfigDataChanged -= value; }
		}

		#region Picasa Uploader Properties

		public string Picasa_Username { get; set; }
		public string Picasa_Password { get; set; }

		[XmlIgnore]
		public string Picasa_UnsavedPassword { get; set; }

		#endregion

		#region Singleton instance

		private static UploadConfigData s_Instance;
		public static UploadConfigData Instance
		{
			get
			{
				if (s_Instance == null)
				{
					LoadConfiguration();
					if (s_Instance == null)
						s_Instance = new UploadConfigData();
				}
				return s_Instance;
			}
		}

		#endregion

		#region Constructor

		private UploadConfigData()
		{
		}

		#endregion

		#region Serialization Methods

		public void SaveConfiguration()
		{
			string xmlData = SerializeConfiguration();
			try
			{
				StreamWriter writer = File.CreateText(SystemHelper.ConfigXmlPath);

				writer.Write(xmlData);
				writer.Close();
			}
			catch (IOException e)
			{
				Aero.DisplayErrorMessage(
						Properties.Resources.SerializeConfigCaption,
						Properties.Resources.SerializeConfigMessage,
						e.ToString());
			}
			RaiseUploadConfigDataChanged(null);
		}

		private static void LoadConfiguration()
		{
			string xmlData = string.Empty;
			try
			{
				StreamReader reader = new StreamReader(SystemHelper.ConfigXmlPath);
				xmlData = reader.ReadToEnd();
				reader.Close();
			}
			catch (IOException e)
			{
				Aero.DisplayErrorMessage(
						Properties.Resources.DeserializeConfigCaption,
						Properties.Resources.DeserializeConfigMessage,
						e.ToString());
			}

			if (!string.IsNullOrEmpty(xmlData))
			{
				s_Instance = DeserializeConfiguration(xmlData);

				if (s_Instance == null)
				{
					Aero.DisplayErrorMessage(
							Properties.Resources.SerializeConfigCaption,
							Properties.Resources.SerializeConfigMessage,
							Properties.Resources.InvalidFileData + "\r\n" + xmlData);
					return;
				}


				// TODO: Serialize values
			}

		}

		private String SerializeConfiguration()
		{
			/*
			StorageConfiguration config = CreateConfigObject();
			if (!config.SavePassword)
			{
					config.Password = string.Empty;
			}
			*/

			try
			{
				String XmlizedString = null;
				MemoryStream memoryStream = new MemoryStream();
				XmlSerializer xs = new XmlSerializer(typeof(UploadConfigData));
				XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

				xs.Serialize(xmlTextWriter, this);
				memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
				XmlizedString = encoding.GetString(memoryStream.ToArray());
				return XmlizedString;
			}
			catch (Exception e)
			{
				Aero.DisplayErrorMessage(
						Properties.Resources.SerializeConfigCaption,
						Properties.Resources.SerializeConfigMessage,
						e.ToString());

				return null;
			}
		}

		private static UploadConfigData DeserializeConfiguration(String pXmlizedString)
		{
			XmlSerializer xs = new XmlSerializer(typeof(UploadConfigData));
			MemoryStream memoryStream = new MemoryStream(encoding.GetBytes(pXmlizedString));
			XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
			try
			{
				return xs.Deserialize(memoryStream) as UploadConfigData;
			}
			catch (InvalidOperationException e)
			{
				Aero.DisplayErrorMessage(
						Properties.Resources.SerializeConfigCaption,
						Properties.Resources.SerializeConfigMessage,
						e.InnerException.ToString());
				return null;
			}
		}

		#endregion

		private void RaiseUploadConfigDataChanged(EventArgs e)
		{
			if (m_UploadConfigDataChanged != null)
				m_UploadConfigDataChanged(this, e);
		}
	}
}
